
#include "role.h"
#include "config.h"
#include "effect.h"
#include "sdl_func.h"
#include "map.h"

extern SDL_Surface * screen;
extern SDL_Surface * tiles;

void RoleInit(Role *r, int g, Uint8 X, Uint8 Y)
{
    r->glyph = g;
    r->pos.x = r->old_pos.x = X;
    r->pos.y = r->old_pos.y = Y;
    r->path_point_index = -1;
    r->dest_grid = -1;
}

void RoleDraw(Role *r)
{
    SDL_Rect src_rect, dest_rect;
    src_rect.w = dest_rect.w = TILE_WIDTH;
    src_rect.h = dest_rect.h = TILE_HEIGHT;
    src_rect.x = r->glyph % TILE_COLS * TILE_WIDTH;
    src_rect.y = r->glyph / TILE_COLS * TILE_HEIGHT;
    dest_rect.x = MAP_OFFSETX + r->pos.x * TILE_WIDTH;
    dest_rect.y = MAP_OFFSETY + r->pos.y * TILE_HEIGHT;
    SDL_BlitSurface(tiles, &src_rect, screen, &dest_rect);
}

void RoleMove(Role *r, Dir d)
{
    r->old_pos.x = r->pos.x;
    r->old_pos.y = r->pos.y;
    r->dir = d;

    switch(d) {
    case dir_up:
        if (MapBlock(r->pos.x, r->pos.y - 1) == 0)
            r->pos.y -= 1;
        break;
    case dir_down:
        if (MapBlock(r->pos.x, r->pos.y + 1) == 0)
            r->pos.y += 1;
        break;
    case dir_left:
        if (MapBlock(r->pos.x - 1, r->pos.y) == 0)
            r->pos.x -= 1;
        break;
    case dir_right:
        if (MapBlock(r->pos.x + 1, r->pos.y) == 0)
            r->pos.x += 1;
        break;
    case dir_upleft:
        if (MapBlock(r->pos.x - 1, r->pos.y - 1) == 0) {
            r->pos.x -= 1;
            r->pos.y -= 1;
        }
        break;
    case dir_upright:
        if (MapBlock(r->pos.x + 1, r->pos.y - 1) == 0) {
            r->pos.x += 1;
            r->pos.y -= 1;
        }
        break;
    case dir_downleft:
        if (MapBlock(r->pos.x - 1, r->pos.y + 1) == 0) {
            r->pos.x -= 1;
            r->pos.y += 1;
        }
        break;
    case dir_downright:
        if (MapBlock(r->pos.x + 1, r->pos.y + 1) == 0) {
            r->pos.x += 1;
            r->pos.y += 1;
        }
        break;
    }

    printf("Position: %d, %d\n", r->pos.x, r->pos.y);

    if ( (r->old_pos.x != r->pos.x) ||
         (r->old_pos.y != r->pos.y) ) {
        ClipRect rect;
        GetClipRect(&rect, r->old_pos, r->pos);

        MapDraw(rect);
        RoleDraw(r);
        SDL_Flip(screen);
    }
}

void RoleMoveTo(Role *r, int x, int y)
{
    r->old_pos = r->pos;
    r->pos.x = x;
    r->pos.y = y;

    if ( (r->old_pos.x != r->pos.x) ||
         (r->old_pos.y != r->pos.y) ) {
        ClipRect rect;
        GetClipRect(&rect, r->old_pos, r->pos);

        MapDraw(rect);
        RoleDraw(r);
        SDL_Flip(screen);
    }
    
}

void RoleCastSpell(Role *r, Dir d)
{
    int glyph;
    char ex, ey;

    PlayWavSound(0);

    switch(d) {
    case dir_up:
        if (r->pos.y == 0)
            return;
        else {
            ex = r->pos.x;
            ey = r->pos.y - 1;
        }
        glyph = FIRELINE_GLYPH;
        break;

    case dir_down:
        if (r->pos.y == MAP_ROWS - 1)
            return;
        else {
            ex = r->pos.x;
            ey = r->pos.y + 1;
        }
        glyph = FIRELINE_GLYPH;
        break;

    case dir_left:
        if (r->pos.x == 0)
            return;
        else {
            ex = r->pos.x - 1;
            ey = r->pos.y;
        }
        glyph = FIRELINE_GLYPH + 1;
        break;

    case dir_right:
        if (r->pos.x == MAP_COLS - 1)
            return;
        else {
            ex = r->pos.x + 1;
            ey = r->pos.y;
        }
        glyph = FIRELINE_GLYPH + 1;
        break;

    case dir_upleft:
        if (r->pos.x == 0 || r->pos.y == 0)
            return;
        else {
            ex = r->pos.x - 1;
            ey = r->pos.y - 1;
        }
        glyph = FIRELINE_GLYPH + 2;
        break;

    case dir_downright:
        if (r->pos.x == MAP_COLS - 1 ||
            r->pos.y == MAP_ROWS - 1)
            return;
        else {
            ex = r->pos.x + 1;
            ey = r->pos.y + 1;
        }
        glyph = FIRELINE_GLYPH + 2;
        break;

    case dir_upright:
        if (r->pos.x == MAP_COLS - 1 ||
            r->pos.y == 0)
            return;
        else {
            ex = r->pos.x + 1;
            ey = r->pos.y - 1;
        }
        glyph = FIRELINE_GLYPH + 3;
        break;

    case dir_downleft:
        if (r->pos.y == MAP_ROWS - 1 ||
            r->pos.x == 0)
            return;
        else {
            ex = r->pos.x - 1;
            ey = r->pos.y + 1;
        }
        glyph = FIRELINE_GLYPH + 3;
        break;
    }

    Effect e;
    LineEffectInit(&e, glyph, ex, ey, d, 5, 25);
    LineEffectDraw(&e);
}

void RoleClearPath(Role *r)
{
    int i;
    for(i = 0; i < MAP_COLS * MAP_ROWS; i ++)
        r->path[i] = -1;
    r->path_point_index = -1;
}

boolean RoleHasPath(Role *r){
    if(r->path[0] == -1)
        return false;
    else
        return true;
}

void RoleFollowPath(Role *r)
{
    if(r->path_point_index >= MAP_COLS * MAP_ROWS
        || r->path[r->path_point_index + 1] == -1){
        RoleClearPath(r);
    }
    else {
        int next_grid = r->path[++ r->path_point_index];
        int new_x = next_grid % MAP_COLS;
        int new_y = next_grid / MAP_COLS;
        RoleMoveTo(r, new_x, new_y);
        /* if (r->pos.x = new_x) { */
        /*     if(new_y < r->pos.y) */
        /*         RoleMove(r, dir_up); */
        /*     else */
        /*         RoleMove(r, dir_down); */
        /* } */
        /* else if(r->pos.y = new_y) { */
        /*     if(new_x < r->pos.x) */
        /*         RoleMove(r, dir_left); */
        /*     else */
        /*         RoleMove(r, dir_right); */
        /* } */
        /* else if(new_x < r->pos.x && new_y < r->pos.y) */
        /*     RoleMove(r, dir_upleft); */
        /* else if(new_x < r->pos.x && new_y > r->pos.y) */
        /*     RoleMove(r, dir_downleft); */
        /* else if(new_x > r->pos.x && new_y < r->pos.y) */
        /*     RoleMove(r, dir_upright); */
        /* else if(new_x > r->pos.x && new_y > r->pos.y) */
        /*     RoleMove(r, dir_downright); */
    }
}
